/*=========================================================================

Program:   Virtual Surgery
Language:  C++
Date:      2009-9-1
Version:   0.1
Mail:		   nelfylee@gmail.com

Copyright (c) 2009 Nelfy Lee. All rights reserved.

=========================================================================*/
#include "PipelineTreeView.h"
#include "Source.h"
#include "SourceIO.h"
#include "DisplayModel.h"

#include "PipelineModel.h"
#include <QStandardItemModel>
#include <QDebug>




PipelineTreeView::PipelineTreeView(QWidget *parent) : QTreeView(parent) 
{
	m_menu = new QMenu(this);
	//setHeaderHidden(true);
	setAnimated(true);
	setAutoScroll(true);
	setWordWrap(true);


	// set as base source
	m_actionBase = m_menu->addAction(tr("Apply"));
	connect(m_actionBase, SIGNAL(triggered()), SLOT(slotApplySourceTo2DViews()));

	// hide the source if it is volume rendering
	m_actionHide = m_menu->addAction(tr("Blend"));
	m_actionHide->setCheckable(false);
	connect(m_actionHide, SIGNAL(triggered()), SLOT(slotBlendImage()));

	m_actionSave = m_menu->addAction(tr("Save"));
	connect(m_actionSave, SIGNAL(triggered()), SLOT(slotSaveSource()));

	m_menu->addSeparator();

	m_actionDelete = m_menu->addAction(tr("Delete"));
	connect(m_actionDelete, SIGNAL(triggered()), SLOT(slotRemoveSource()));

	connect(this, SIGNAL(clicked(const QModelIndex&)), SLOT(slotItemClicked(const QModelIndex&)));
}


PipelineTreeView::~PipelineTreeView()
{
}


void PipelineTreeView::postShow()
{
	setColumnWidth(1, 25);
	setColumnWidth(2, 25);
	//setColumnWidth(3, 25);
	setColumnWidth(0, viewport()->rect().width()-55);
}


void PipelineTreeView::slotItemClicked(const QModelIndex& index)
{
	switch(index.column())
	{
	case 0:
		{
			Source *source = currentSource();
			if ( source)
			{
				emit emitSourceSelected(index);
				emit emitSourceSelected(source->fileName());
			}
			break;
		}
	case 1:
		{
			slotDisplayOutline();
			break;
		}
	case 2:
		{
			slotDisplayModel();
			break;
		}
// 	case 3:
// 		{
// 			slotDisplayVolume();
// 			break;
// 		}
	}
}


void
PipelineTreeView::slotSourceAdded(const QModelIndex& index)
{
 	expand(index);

	if ( index.parent().isValid())
		expand(index.parent());
}


void 
PipelineTreeView::slotRefresh()
{
	repaint(frameRect());
}


void
PipelineTreeView::slotApplySourceTo2DViews()
{
	QModelIndex index = currentIndex();

	//void emitDisplay2DSlices(const QModelIndex&);
	emit emitSetBaseSource(index);

	//PipelineModel *pipeline = static_cast<PipelineModel*>(model());

	//pipeline->setBaseSource(index);
}


void 
PipelineTreeView::slotSaveSource()
{
	QModelIndex index = currentIndex();
	PipelineModel *pipeline = static_cast<PipelineModel*>(model());

	Source *source = (Source*)(pipeline->itemFromIndex(index));

	if ( !source)
		return;

	SourceIO::write(source);

	//slotRefresh();
}


void 
PipelineTreeView::slotRemoveSource()
{
	QModelIndex index = currentIndex();
	PipelineModel *pipeline = static_cast<PipelineModel*>(model());
	
	pipeline->removeSource(index);
	//updateGeometries();

	slotRefresh();
}



void 
PipelineTreeView::slotBlendImage()
{
	bool status = m_displayModel->isDisplaying2D(currentIndex());

	emit emitBlendImage(currentIndex(), !status);

	//m_actionHide->setChecked(m_displayModel->isDisplaying2D(currentIndex()));
}

void
PipelineTreeView::slotDisplayOutline()
{
	emit emitDisplayOutline(currentIndex(), !m_displayModel->isDisplayingOutline(currentIndex()));
}


void
PipelineTreeView::slotDisplayModel()
{
	emit emitDisplayModel(currentIndex(), !m_displayModel->isDisplayingModel(currentIndex()));
}


// void
// PipelineTreeView::slotDisplayVolume()
// {
// 	emit emitDisplayVolume(currentIndex(), !m_displayModel->isDisplayingVolume(currentIndex()));
// }
// 

void 
PipelineTreeView::mouseReleaseEvent(QMouseEvent *event)
{
	QAbstractItemView::mouseReleaseEvent(event);

	if ( event->button() == Qt::RightButton)
	{
		Source *source = currentSource();
		
		if ( source)
		{
			m_menu->popup(event->globalPos());
		}
	}
}


Source* 
PipelineTreeView::currentSource()
{
	QModelIndex index = currentIndex();

	if ( index.isValid())
	{
		PipelineModel *smodel = static_cast<PipelineModel*>(model());
		Source *source = smodel->sourceFromIndex(index);
		
		return source;
	}
	else
		return NULL;
}


void PipelineTreeView::setDisplayModel(DisplayModel* dm)
{
	m_displayModel = dm;

	connect(this, SIGNAL(emitDisplayOutline(const QModelIndex&, bool)),	m_displayModel, SLOT(slotDisplayOutline(const QModelIndex&, bool)));
	connect(this, SIGNAL(emitDisplayModel(const QModelIndex&, bool)),m_displayModel, SLOT(slotDisplayModel(const QModelIndex&, bool)));
	//connect(this, SIGNAL(emitDisplayVolume(const QModelIndex&, bool)), m_displayModel, SLOT(slotDisplayVolume(const QModelIndex&, bool)));
	connect(this, SIGNAL(emitDisplay2DSlices(const QModelIndex&, bool)),m_displayModel, SLOT(slotDisplay2DSlices(const QModelIndex&, bool)));
	connect(this, SIGNAL(emitSetBaseSource(const QModelIndex&)),m_displayModel, SLOT(slotSetBaseSource(const QModelIndex&)));
	//connect(dm, SIGNAL(emitSourceAdded(const QModelIndex&)),SLOT(slotSourceAdded(const QModelIndex&)));
	connect(this, SIGNAL(emitBlendImage(const QModelIndex&, bool)), m_displayModel, SLOT(slotBlendImage(const QModelIndex&, bool)));
}

PipelineModel * PipelineTreeView::pipelineModel()
{
	return static_cast<PipelineModel*>(model());
}

void PipelineTreeView::setModel( QAbstractItemModel *model )
{
	QTreeView::setModel(model);

	connect(this, SIGNAL(emitSourceSelected(const QModelIndex&)), model, SIGNAL(emitSourceSelected(const QModelIndex&)));
	connect(this, SIGNAL(emitUpdateModel()), model, SIGNAL(layoutChanged()));
}

void PipelineTreeView::slotCreateSurfaceSource()
{
	QModelIndex index = currentIndex();

	pipelineModel()->createSurfaceSource(index);
}